﻿using QFramework;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace HKTools
{
    public enum HK_PanelType
    {
        GloblaType,    // 全局面板
        HierarchyType  // 层级面板
    }

    public interface IHK_UISystem : ISystem
    {
        /// <summary>
        /// 当前打开的 层级面板
        /// </summary>
        BindableProperty<HK_PanelName> CurrentHierarchyPanel { get; }

        /// <summary>
        /// 打开 指定面板
        /// </summary>
        void OpenAppointPanel(HK_PanelName panelName, string message = null);

        /// <summary>
        /// 关闭 指定面板
        /// </summary>
        void CloseGlobalPanel(HK_PanelName panelName);

        /// <summary>
        /// 关闭 层级面板
        /// </summary>
        void CloseHierarchyPanel();
    }

    /// <summary>
    /// UI系统，负责管理UI面板的打开关闭，及其层级关系和排序。
    /// </summary>
    public class HK_UISystem : AbstractSystem, IHK_UISystem
    {
        public BindableProperty<HK_PanelName> CurrentHierarchyPanel { get; } = new BindableProperty<HK_PanelName>();

        Canvas curCanvas;

        RectTransform forDesign_RTF;
        RectTransform forShow_RTF;

        // 所有 Panel 的字典
        Dictionary<HK_PanelName, HK_BasePanel> allPanels_Dic;

        // 当前 开启的 全局面板
        HashSet<HK_BasePanel> globalPanels_HashSet;

        // 当前 加载的 层级面板
        Stack<HK_BasePanel> hierarchyPanels_Stack;

        HK_UIConfig config;

        protected override void OnInit()
        {
            curCanvas = GameObject.Find("UIRoot").GetComponent<Canvas>();

            forDesign_RTF = curCanvas.transform.Find("ForDesign").GetComponent<RectTransform>();
            forShow_RTF = curCanvas.transform.Find("ForShow").GetComponent<RectTransform>();

            // 隐藏 ForDesign 下面的子物体
            for (int i = 0; i < forDesign_RTF.childCount; i++)
            {
                forDesign_RTF.GetChild(i).gameObject.SetActive(false);
            }

            config = Resources.Load<HK_UIConfig>("HK_UIConfig");

            allPanels_Dic = new Dictionary<HK_PanelName, HK_BasePanel>();
            globalPanels_HashSet = new HashSet<HK_BasePanel>();
            hierarchyPanels_Stack = new Stack<HK_BasePanel>();
        }

        HK_BasePanel GetPanel(HK_PanelName panelName)
        {
            // 如果 字典中未查询到该Panel，则实例化一个
            if (!allPanels_Dic.TryGetValue(panelName, out var panel))
            {
                var panelItem = config.UIPanels.FirstOrDefault(item => item.PanelName.value == panelName);

                if (panelItem != null)
                {
                    panel = GameObject.Instantiate(panelItem.Panel, forShow_RTF);
                    panel.PanelType = panelItem.PanelType;
                    panel.PanelName.value = panelName;
                    panel.Order = panelItem.Order;

                    if (panel.name.Contains("Clone"))
                        panel.name = panel.name.Replace("(Clone)", "");

                    panel.Init();

                    allPanels_Dic.Add(panelName, panel);
                }
            }

            return panel;
        }

        public void OpenAppointPanel(HK_PanelName panelName, string message = null)
        {
            var panel = GetPanel(panelName);

            if (panel == null) return;

            switch (panel.PanelType)
            {
                case HK_PanelType.GloblaType:   // 如果是全局面板
                    if (globalPanels_HashSet.Add(panel))
                    {
                        panel.Open(message);
                    }
                    break;
                case HK_PanelType.HierarchyType:    // 如果是层级面板
                    if (hierarchyPanels_Stack.Count > 0)
                    {
                        hierarchyPanels_Stack.Peek().Pause();
                    }

                    panel.Open(message);

                    hierarchyPanels_Stack.Push(panel);

                    CurrentHierarchyPanel.Value = panelName;

                    break;
            }

            // 打开一个新的Panel时，对所有面板重新进行排序
            var sortedPanels = allPanels_Dic.Values
                .OrderBy(item => item.Order)
                .ToList();

            for (int i = 0; i < sortedPanels.Count; i++)
            {
                sortedPanels[i].transform.SetSiblingIndex(i);
            }
        }

        // 根据 HK_PanelName 判定是不是全局面板
        public void CloseGlobalPanel(HK_PanelName panelName)
        {
            // 如果该Panel未打开
            if (allPanels_Dic.TryGetValue(panelName, out var curPanel))
            {
                // 不是全局面板，则返回
                if (globalPanels_HashSet.Remove(curPanel))
                {
                    curPanel.Close();
                }
                else
                {
                    Debug.LogWarning(panelName.ToString() + " 不是 GlobalPanel");
                }
            }
        }

        public void CloseHierarchyPanel()
        {
            if (hierarchyPanels_Stack.Count > 0)
            {
                hierarchyPanels_Stack.Pop().Close();
            }

            if (hierarchyPanels_Stack.Count > 0)
            {
                HK_BasePanel panel = hierarchyPanels_Stack.Peek();
                panel.Resume();
                CurrentHierarchyPanel.Value = panel.PanelName;
            }
        }
    }
}